﻿using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Windows.Controls;

namespace Riba.Tools.Controls
{
	public class TextBoxWithMaxLengthFromStringLengthAttribute : TextBox
	{
		public TextBoxWithMaxLengthFromStringLengthAttribute()
		{
			Loaded += TextBoxEx_Loaded;
		}

		void TextBoxEx_Loaded(object sender, System.Windows.RoutedEventArgs e)
		{
			var bindingExpression = GetBindingExpression(TextProperty);
			if (bindingExpression == null)
				return;

			var path = bindingExpression.ParentBinding.Path.Path;  //sample: FirstName
			if (string.IsNullOrEmpty(path))
				return;

			//var prop = bindingExpression.DataItem.GetType().GetProperty(path);  works only with simple paths like 'FirstName'. Complex paths like 'CurrentEntity.Title' need Helper GetPropertyByPath
			var prop = GetPropertyByPath(bindingExpression.DataItem, path);
			if (prop == null)
				return;
			var stringLengthAttr = prop.GetCustomAttributes(typeof(StringLengthAttribute), true).FirstOrDefault() as StringLengthAttribute;

			if (stringLengthAttr == null)
				return;

			MaxLength = stringLengthAttr.MaximumLength;
		}


		// http://stackoverflow.com/questions/2398657/retrieve-system-componentmodel-dataannotations-displayattribute-properties-from-v

		private static PropertyInfo GetPropertyByPath(object obj, string propertyPath)
		{
			if (obj == null)
				return null;

			var type = obj.GetType();
			PropertyInfo propertyInfo = null;

			foreach (var part in propertyPath.Split(new[] {'.'}))
			{
				// On subsequent iterations use the type of the property         
				if (propertyInfo != null)
					type = propertyInfo.PropertyType;

				// Get the property at this part   
				propertyInfo = type.GetProperty(part);

				// Not found     
				if (propertyInfo == null)
					return null;

				// Can't navigate into indexer       
				if (propertyInfo.GetIndexParameters().Length > 0)
					return null;
			}

			return propertyInfo;
		}
	}
}
